/**
 * @file    threads_pool.h
 * @brief   线程池模块头文件
 * 
 * @details 该模块定义了一个线程池的实现，用于管理多个工作线程和处理任务队列。
 *          线程池可以动态添加/删除线程和任务，支持任务取消和线程池安全销毁。
 * 
 * @author  连佳炜
 * @date    2025-09-12
 * @version 1.0.0
 * 
 * @note    使用前需确保系统支持pthread线程库
 * @warning 线程池销毁时会等待所有任务完成，请确保任务函数能够正常退出
 */

#ifndef __THREADS_POOL_H__
#define __THREADS_POOL_H__

#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

/**
 * @brief   任务信息结构体
 * @details 用于存储任务的相关信息，包括处理函数和参数，构成双向链表
 */
typedef
struct taskMsg
{
    void* (* handleFuncPt)(void* arg);  /**< 处理函数地址 */
    void* handleFuncArg;                /**< 处理函数参数 */
    struct taskMsg* prevTaskMsgStPt;    /**< 上个任务信息地址 */
    struct taskMsg* nextTaskMsgStPt;    /**< 下个任务信息地址 */
}
TaskMsg_st, *TaskMsg_st_pt;

/**
 * @brief   线程信息结构体
 * @details 用于存储线程的相关信息，构成双向链表
 */
typedef
struct threadMsg
{
    pthread_t tid;                      /**< ID */
    struct threadMsg* prevTrdMsgStPt;   /**< 上个线程信息地址 */
    struct threadMsg* nextTrdMsgStPt;   /**< 下个线程信息地址 */
}
ThreadMsg_st, *ThreadMsg_st_pt;

/**
 * @brief   线程池信息结构体
 * @details 包含线程池的所有状态信息和管理结构
 */
typedef
struct threadsPoolMsg
{
    pthread_mutex_t mtxUn;                  /**< 互斥锁 */
    pthread_cond_t codUn;                   /**< 条件量 */
    bool shutDown;                          /**< 销毁标记 */
    int waitingTasksCot;                    /**< 等待任务量 */
    int activeThreadsCot;                   /**< 活跃线程量 */
    int maxWaitingTasksCot;                 /**< 最大等待任务量 */
    int maxActiveThreadsCot;                /**< 最大活跃线程量 */
    TaskMsg_st_pt tasksLinkedQueueEntr;     /**< 任务链队入口 */
    ThreadMsg_st_pt threadsLinkedListEntr;  /**< 线程链表入口 */
}
ThreadsPoolMsg_st, *ThreadsPoolMsg_st_pt;

/**
 * @def     READY_CLEAN_UP_AND_LOCK(cleanUpHandleFuncPt, mtxUnPt)
 * @brief   准备清理并加锁的宏
 * @details 压入清理处理函数并对互斥锁加锁，用于实现线程安全
 * 
 * @param   cleanUpHandleFuncPt 清理处理函数指针
 * @param   mtxUnPt             互斥锁指针
 */
#define READY_CLEAN_UP_AND_LOCK(cleanUpHandleFuncPt, mtxUnPt) \
    pthread_cleanup_push((cleanUpHandleFuncPt), (mtxUnPt)); \
    pthread_mutex_lock((mtxUnPt));

/**
 * @def     UNLOCK_AND_CANCEL_CLEAN_UP(mtxUnPt)
 * @brief   解锁并取消清理的宏
 * @details 对互斥锁解锁并弹出清理处理函数（不执行）
 * 
 * @param   mtxUnPt 互斥锁指针
 */
#define UNLOCK_AND_CANCEL_CLEAN_UP(mtxUnPt) \
    pthread_mutex_unlock((mtxUnPt)); \
    pthread_cleanup_pop(0);

/**
 * @def     SHOW_DEBUG
 * @brief   调试信息显示宏
 * @details 显示当前文件名、函数名和行号信息
 */
#define SHOW_DEBUG \
    fprintf(stderr, "| FILE: %s | FUNC: %s  | LINE: %d  |\n", __FILE__, __FUNCTION__, __LINE__);

/**
 * @brief   创建新的线程池
 * 
 * @param   orgActiveThreadsCot    初始活跃线程数量
 * @param   maxWaitingTasksCot     最大等待任务数量
 * @param   maxActiveThreadsCot    最大活跃线程数量
 * 
 * @return  成功返回线程池指针，失败返回NULL
 * 
 * @note    初始线程数量不能为0，最大数量限制必须合理
 */
ThreadsPoolMsg_st_pt getNewThreadsPoolMsg (int orgActiveThreadsCot, int maxWaitingTasksCot, int maxActiveThreadsCot);

/**
 * @brief   添加新任务到线程池
 * 
 * @param   trdsPolMsgStPt 线程池指针
 * @param   handleFuncPt   任务处理函数指针
 * @param   handleFuncArg  任务处理函数参数
 * 
 * @return  成功返回0，失败返回-1
 * 
 * @note    如果任务队列已满，添加会失败
 */
int addNewTask (ThreadsPoolMsg_st_pt trdsPolMsgStPt, void* (* handleFuncPt)(void* arg), void* handleFuncArg);

/**
 * @brief   从线程池中移除指定任务
 * 
 * @param   trdsPolMsgStPt     线程池指针
 * @param   destHandleFuncPt   要移除的任务处理函数指针
 * 
 * @return  成功返回0，失败返回-1
 * 
 * @note    只能移除尚未开始执行的任务
 */
int reduceTask (ThreadsPoolMsg_st_pt trdsPolMsgStPt, void* (* destHandleFuncPt)(void* arg));

/**
 * @brief   向线程池中添加新线程
 * 
 * @param   trdsPolMsgStPt 线程池指针
 * 
 * @return  成功返回0，失败返回-1
 * 
 * @note    线程数量不能超过最大限制
 */
int addThread (ThreadsPoolMsg_st_pt trdsPolMsgStPt);

/**
 * @brief   从线程池中移除线程
 * 
 * @param   trdsPolMsgStPt 线程池指针
 * 
 * @return  成功返回0，失败返回-1
 * 
 * @note    至少保留一个活跃线程
 */
int reduceThread (ThreadsPoolMsg_st_pt trdsPolMsgStPt);

/**
 * @brief   销毁线程池
 * 
 * @param   trdsPolMsgStPt 线程池指针
 * 
 * @note    会等待所有任务完成后再销毁资源
 * @warning 线程池销毁后不能再使用
 */
void destroyThreadsPoolMsg (ThreadsPoolMsg_st_pt trdsPolMsgStPt);


#endif